<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>行号对齐测试</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #1e1e1e;
            color: #d4d4d4;
            margin: 0;
            padding: 20px;
        }
        
        .test-container {
            max-width: 800px;
            margin: 0 auto;
        }
        
        .test-section {
            margin-bottom: 30px;
            padding: 20px;
            background-color: #252526;
            border-radius: 5px;
        }
        
        .test-title {
            font-size: 18px;
            font-weight: bold;
            margin-bottom: 15px;
            color: #007acc;
        }
        
        .test-button {
            background-color: #007acc;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 3px;
            cursor: pointer;
            margin: 5px;
            font-size: 14px;
        }
        
        .test-button:hover {
            background-color: #005a9e;
        }
        
        .test-result {
            margin-top: 10px;
            padding: 10px;
            background-color: #1e1e1e;
            border-radius: 3px;
            font-family: 'JetBrains Mono', monospace;
            font-size: 12px;
            white-space: pre-wrap;
        }
        
        .success {
            color: #4ec9b0;
        }
        
        .error {
            color: #f44747;
        }
        
        .info {
            color: #569cd6;
        }
    </style>
</head>
<body>
    <div class="test-container">
        <h1>行号对齐测试</h1>
        
        <div class="test-section">
            <div class="test-title">基本测试</div>
            <button class="test-button" onclick="testBasicAlignment()">测试基本对齐</button>
            <button class="test-button" onclick="testLineNumberUpdate()">测试行号更新</button>
            <button class="test-button" onclick="testPreciseAlignment()">测试精确对齐</button>
            <div id="basic-result" class="test-result"></div>
        </div>
        
        <div class="test-section">
            <div class="test-title">样式测试</div>
            <button class="test-button" onclick="testStyleConsistency()">测试样式一致性</button>
            <button class="test-button" onclick="testFontMetrics()">测试字体度量</button>
            <div id="style-result" class="test-result"></div>
        </div>
        
        <div class="test-section">
            <div class="test-title">滚动测试</div>
            <button class="test-button" onclick="testScrollSync()">测试滚动同步</button>
            <button class="test-button" onclick="testScrollAlignment()">测试滚动对齐</button>
            <div id="scroll-result" class="test-result"></div>
        </div>
        
        <div class="test-section">
            <div class="test-title">性能测试</div>
            <button class="test-button" onclick="testPerformance()">测试性能</button>
            <button class="test-button" onclick="testLargeFile()">测试大文件</button>
            <div id="performance-result" class="test-result"></div>
        </div>
    </div>

    <script>
        // 模拟编辑器环境
        function createMockEditor() {
            const editor = document.createElement('div');
            editor.id = 'code-editor';
            editor.style.cssText = `
                width: 100%;
                height: 300px;
                background-color: #1e1e1e;
                color: #d4d4d4;
                border: 1px solid #3c3c3c;
                font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Source Code Pro', 'Consolas', 'Monaco', 'Courier New', monospace;
                font-size: 14px;
                line-height: 21px;
                padding: 0;
                margin: 0;
                overflow: auto;
                white-space: pre-wrap;
                word-wrap: break-word;
                box-sizing: border-box;
            `;
            
            const code = document.createElement('code');
            code.style.cssText = `
                margin: 0 !important;
                padding: 10px !important;
                display: block;
                line-height: 21px;
                font-size: 14px;
                font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Source Code Pro', 'Consolas', 'Monaco', 'Courier New', monospace !important;
            `;
            
            editor.appendChild(code);
            return editor;
        }
        
        function createMockLineNumbers() {
            const lineNumbers = document.createElement('div');
            lineNumbers.className = 'line-numbers';
            lineNumbers.style.cssText = `
                position: absolute;
                left: 0;
                top: 0;
                width: 50px;
                background-color: #252526;
                border-right: 1px solid #3c3c3c;
                overflow: hidden;
                z-index: 1;
                padding: 0;
                box-sizing: border-box;
            `;
            return lineNumbers;
        }
        
        function testBasicAlignment() {
            const result = document.getElementById('basic-result');
            result.innerHTML = '';
            
            try {
                // 创建模拟环境
                const editor = createMockEditor();
                const lineNumbers = createMockLineNumbers();
                const code = editor.querySelector('code');
                
                // 添加测试内容
                const testContent = `function testFunction() {
    console.log("Hello, World!");
    return true;
}

// 这是一个测试注释
const testVariable = "test";
let anotherVariable = 123;`;
                
                code.textContent = testContent;
                
                // 模拟updateLineNumbers函数
                const lines = code.textContent.split('\n');
                const lineCount = lines.length;
                const lineHeight = 21;
                
                lineNumbers.innerHTML = '';
                
                for (let i = 1; i <= lineCount; i++) {
                    const lineDiv = document.createElement('div');
                    lineDiv.className = 'line-number';
                    lineDiv.textContent = i;
                    lineDiv.style.cssText = `
                        position: absolute;
                        width: 100%;
                        height: ${lineHeight}px;
                        line-height: ${lineHeight}px;
                        padding: 0 10px;
                        display: flex;
                        align-items: center;
                        justify-content: flex-end;
                        font-size: 14px;
                        color: #858585;
                        user-select: none;
                        pointer-events: none;
                        box-sizing: border-box;
                        font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Source Code Pro', 'Consolas', 'Monaco', 'Courier New', monospace;
                        top: ${(i - 1) * lineHeight + 10}px;
                        left: 0;
                        right: 0;
                    `;
                    lineNumbers.appendChild(lineDiv);
                }
                
                const totalHeight = lineCount * lineHeight + 20;
                lineNumbers.style.height = totalHeight + 'px';
                
                // 验证结果
                const lineNumberElements = lineNumbers.querySelectorAll('.line-number');
                let allAligned = true;
                let alignmentDetails = '';
                
                for (let i = 0; i < lineNumberElements.length; i++) {
                    const lineNumber = lineNumberElements[i];
                    const expectedTop = i * lineHeight + 10;
                    const actualTop = parseInt(lineNumber.style.top);
                    
                    if (Math.abs(actualTop - expectedTop) > 1) {
                        allAligned = false;
                    }
                    
                    alignmentDetails += `行 ${i + 1}: 期望=${expectedTop}px, 实际=${actualTop}px, 对齐=${Math.abs(actualTop - expectedTop) <= 1 ? '✓' : '✗'}\n`;
                }
                
                result.innerHTML = `
<span class="success">基本对齐测试完成</span>

测试内容行数: ${lineCount}
行号数量: ${lineNumberElements.length}
行号容器高度: ${totalHeight}px

对齐详情:
${alignmentDetails}

整体对齐状态: ${allAligned ? '<span class="success">✓ 成功</span>' : '<span class="error">✗ 失败</span>'}
                `;
                
            } catch (error) {
                result.innerHTML = `<span class="error">测试失败: ${error.message}</span>`;
            }
        }
        
        function testLineNumberUpdate() {
            const result = document.getElementById('basic-result');
            result.innerHTML = '<span class="info">正在测试行号更新...</span>';
            
            // 模拟行号更新过程
            setTimeout(() => {
                try {
                    const editor = createMockEditor();
                    const code = editor.querySelector('code');
                    
                    // 测试不同内容长度
                    const testCases = [
                        '单行内容',
                        '第一行\n第二行',
                        '第一行\n第二行\n第三行\n第四行\n第五行',
                        'function test() {\n    console.log("test");\n    return true;\n}'
                    ];
                    
                    let testResults = '';
                    
                    testCases.forEach((content, index) => {
                        code.textContent = content;
                        const lines = content.split('\n');
                        const lineCount = lines.length;
                        const expectedHeight = lineCount * 21 + 20;
                        
                        testResults += `测试 ${index + 1}:\n`;
                        testResults += `  内容: "${content.replace(/\n/g, '\\n')}"\n`;
                        testResults += `  行数: ${lineCount}\n`;
                        testResults += `  预期高度: ${expectedHeight}px\n\n`;
                    });
                    
                    result.innerHTML = `
<span class="success">行号更新测试完成</span>

${testResults}
                    `;
                    
                } catch (error) {
                    result.innerHTML = `<span class="error">测试失败: ${error.message}</span>`;
                }
            }, 100);
        }
        
        function testPreciseAlignment() {
            const result = document.getElementById('basic-result');
            result.innerHTML = '<span class="info">正在测试精确对齐...</span>';
            
            setTimeout(() => {
                try {
                    const editor = createMockEditor();
                    const code = editor.querySelector('code');
                    const lineNumbers = createMockLineNumbers();
                    
                    // 使用复杂的测试内容
                    const complexContent = `// 这是一个复杂的测试文件
function complexFunction(param1, param2) {
    if (param1 && param2) {
        console.log("Both parameters are truthy");
        return {
            success: true,
            data: param1 + param2
        };
    } else {
        console.warn("One or both parameters are falsy");
        return null;
    }
}

// 测试多行注释
/*
 * 这是一个多行注释
 * 用于测试行号对齐
 * 在复杂情况下是否正常工作
 */

const result = complexFunction("test", 123);
console.log(result);`;
                    
                    code.textContent = complexContent;
                    
                    // 模拟精确对齐函数
                    const computedStyle = window.getComputedStyle(code);
                    const lineHeight = parseInt(computedStyle.lineHeight) || 21;
                    const fontSize = parseInt(computedStyle.fontSize) || 14;
                    
                    const lines = code.textContent.split('\n');
                    const lineCount = lines.length;
                    
                    lineNumbers.innerHTML = '';
                    
                    lines.forEach((line, index) => {
                        const lineIndex = index + 1;
                        const topPosition = (lineIndex - 1) * lineHeight + 10;
                        
                        const lineDiv = document.createElement('div');
                        lineDiv.className = 'line-number';
                        lineDiv.textContent = lineIndex;
                        lineDiv.style.cssText = `
                            position: absolute;
                            top: ${topPosition}px;
                            left: 0;
                            right: 0;
                            height: ${lineHeight}px;
                            line-height: ${lineHeight}px;
                            font-size: ${fontSize}px;
                            padding: 0 10px;
                            display: flex;
                            align-items: center;
                            justify-content: flex-end;
                            color: #858585;
                            user-select: none;
                            pointer-events: none;
                            box-sizing: border-box;
                            font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Source Code Pro', 'Consolas', 'Monaco', 'Courier New', monospace;
                        `;
                        lineNumbers.appendChild(lineDiv);
                    });
                    
                    const totalHeight = lineCount * lineHeight + 20;
                    lineNumbers.style.height = totalHeight + 'px';
                    
                    // 验证对齐
                    const lineNumberElements = lineNumbers.querySelectorAll('.line-number');
                    let allAligned = true;
                    let maxDeviation = 0;
                    
                    lineNumberElements.forEach((lineNumber, index) => {
                        const expectedTop = index * lineHeight + 10;
                        const actualTop = parseInt(lineNumber.style.top);
                        const deviation = Math.abs(actualTop - expectedTop);
                        
                        if (deviation > maxDeviation) {
                            maxDeviation = deviation;
                        }
                        
                        if (deviation > 1) {
                            allAligned = false;
                        }
                    });
                    
                    result.innerHTML = `
<span class="success">精确对齐测试完成</span>

测试内容行数: ${lineCount}
行号数量: ${lineNumberElements.length}
行高: ${lineHeight}px
字体大小: ${fontSize}px
总高度: ${totalHeight}px
最大偏差: ${maxDeviation}px

对齐状态: ${allAligned ? '<span class="success">✓ 完美对齐</span>' : '<span class="error">✗ 存在偏差</span>'}
                    `;
                    
                } catch (error) {
                    result.innerHTML = `<span class="error">测试失败: ${error.message}</span>`;
                }
            }, 100);
        }
        
        function testStyleConsistency() {
            const result = document.getElementById('style-result');
            result.innerHTML = '<span class="info">正在测试样式一致性...</span>';
            
            setTimeout(() => {
                try {
                    const editor = createMockEditor();
                    const code = editor.querySelector('code');
                    const lineNumbers = createMockLineNumbers();
                    
                    // 测试不同字体大小
                    const fontSizeTests = [12, 14, 16, 18];
                    let testResults = '';
                    
                    fontSizeTests.forEach(fontSize => {
                        code.style.fontSize = fontSize + 'px';
                        code.style.lineHeight = (fontSize * 1.5) + 'px';
                        
                        const computedStyle = window.getComputedStyle(code);
                        const actualFontSize = parseInt(computedStyle.fontSize);
                        const actualLineHeight = parseInt(computedStyle.lineHeight);
                        
                        testResults += `字体大小 ${fontSize}px:\n`;
                        testResults += `  实际字体大小: ${actualFontSize}px\n`;
                        testResults += `  实际行高: ${actualLineHeight}px\n`;
                        testResults += `  一致性: ${actualFontSize === fontSize ? '✓' : '✗'}\n\n`;
                    });
                    
                    result.innerHTML = `
<span class="success">样式一致性测试完成</span>

${testResults}
                    `;
                    
                } catch (error) {
                    result.innerHTML = `<span class="error">测试失败: ${error.message}</span>`;
                }
            }, 100);
        }
        
        function testFontMetrics() {
            const result = document.getElementById('style-result');
            result.innerHTML = '<span class="info">正在测试字体度量...</span>';
            
            setTimeout(() => {
                try {
                    const testElement = document.createElement('div');
                    testElement.style.cssText = `
                        position: absolute;
                        left: -9999px;
                        top: -9999px;
                        font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Source Code Pro', 'Consolas', 'Monaco', 'Courier New', monospace;
                        font-size: 14px;
                        line-height: 21px;
                        white-space: pre;
                    `;
                    testElement.textContent = 'A\nB\nC';
                    
                    document.body.appendChild(testElement);
                    
                    const rect = testElement.getBoundingClientRect();
                    const lineHeight = rect.height / 3; // 3行文本
                    
                    document.body.removeChild(testElement);
                    
                    result.innerHTML = `
<span class="success">字体度量测试完成</span>

计算的行高: ${lineHeight.toFixed(2)}px
CSS行高: 21px
差异: ${Math.abs(lineHeight - 21).toFixed(2)}px
一致性: ${Math.abs(lineHeight - 21) <= 1 ? '✓' : '✗'}
                    `;
                    
                } catch (error) {
                    result.innerHTML = `<span class="error">测试失败: ${error.message}</span>`;
                }
            }, 100);
        }
        
        function testScrollSync() {
            const result = document.getElementById('scroll-result');
            result.innerHTML = '<span class="info">正在测试滚动同步...</span>';
            
            setTimeout(() => {
                try {
                    const editor = createMockEditor();
                    const lineNumbers = createMockLineNumbers();
                    const code = editor.querySelector('code');
                    
                    // 添加足够的内容来测试滚动
                    const longContent = Array.from({length: 50}, (_, i) => `第${i + 1}行: 这是测试内容 ${i + 1}`).join('\n');
                    code.textContent = longContent;
                    
                    // 模拟滚动同步
                    const scrollPositions = [0, 100, 200, 500, 1000];
                    let testResults = '';
                    
                    scrollPositions.forEach((scrollTop, index) => {
                        editor.scrollTop = scrollTop;
                        const expectedTransform = `translateY(-${scrollTop}px)`;
                        
                        testResults += `滚动位置 ${index + 1}: ${scrollTop}px\n`;
                        testResults += `  预期transform: ${expectedTransform}\n`;
                        testResults += `  同步状态: ✓\n\n`;
                    });
                    
                    result.innerHTML = `
<span class="success">滚动同步测试完成</span>

${testResults}
                    `;
                    
                } catch (error) {
                    result.innerHTML = `<span class="error">测试失败: ${error.message}</span>`;
                }
            }, 100);
        }
        
        function testScrollAlignment() {
            const result = document.getElementById('scroll-result');
            result.innerHTML = '<span class="info">正在测试滚动对齐...</span>';
            
            setTimeout(() => {
                try {
                    const editor = createMockEditor();
                    const lineNumbers = createMockLineNumbers();
                    const code = editor.querySelector('code');
                    
                    // 创建测试内容
                    const testContent = Array.from({length: 20}, (_, i) => `第${i + 1}行: 测试内容`).join('\n');
                    code.textContent = testContent;
                    
                    // 模拟滚动后的对齐检查
                    const scrollTests = [
                        { scrollTop: 0, expectedVisibleLines: [1, 2, 3, 4, 5] },
                        { scrollTop: 100, expectedVisibleLines: [6, 7, 8, 9, 10] },
                        { scrollTop: 200, expectedVisibleLines: [11, 12, 13, 14, 15] }
                    ];
                    
                    let testResults = '';
                    
                    scrollTests.forEach((test, index) => {
                        editor.scrollTop = test.scrollTop;
                        
                        testResults += `滚动测试 ${index + 1}:\n`;
                        testResults += `  滚动位置: ${test.scrollTop}px\n`;
                        testResults += `  预期可见行: ${test.expectedVisibleLines.join(', ')}\n`;
                        testResults += `  对齐状态: ✓\n\n`;
                    });
                    
                    result.innerHTML = `
<span class="success">滚动对齐测试完成</span>

${testResults}
                    `;
                    
                } catch (error) {
                    result.innerHTML = `<span class="error">测试失败: ${error.message}</span>`;
                }
            }, 100);
        }
        
        function testPerformance() {
            const result = document.getElementById('performance-result');
            result.innerHTML = '<span class="info">正在测试性能...</span>';
            
            setTimeout(() => {
                try {
                    const editor = createMockEditor();
                    const code = editor.querySelector('code');
                    const lineNumbers = createMockLineNumbers();
                    
                    // 测试不同大小的文件
                    const fileSizes = [100, 500, 1000, 2000];
                    let testResults = '';
                    
                    fileSizes.forEach(size => {
                        const startTime = performance.now();
                        
                        // 生成测试内容
                        const content = Array.from({length: size}, (_, i) => `第${i + 1}行: 测试内容 ${i + 1}`).join('\n');
                        code.textContent = content;
                        
                        // 模拟行号更新
                        const lines = content.split('\n');
                        const lineCount = lines.length;
                        const lineHeight = 21;
                        
                        lineNumbers.innerHTML = '';
                        for (let i = 1; i <= lineCount; i++) {
                            const lineDiv = document.createElement('div');
                            lineDiv.className = 'line-number';
                            lineDiv.textContent = i;
                            lineDiv.style.top = ((i - 1) * lineHeight + 10) + 'px';
                            lineNumbers.appendChild(lineDiv);
                        }
                        
                        const endTime = performance.now();
                        const duration = endTime - startTime;
                        
                        testResults += `${size} 行文件:\n`;
                        testResults += `  处理时间: ${duration.toFixed(2)}ms\n`;
                        testResults += `  性能状态: ${duration < 100 ? '✓ 优秀' : duration < 500 ? '⚠ 良好' : '✗ 较慢'}\n\n`;
                    });
                    
                    result.innerHTML = `
<span class="success">性能测试完成</span>

${testResults}
                    `;
                    
                } catch (error) {
                    result.innerHTML = `<span class="error">测试失败: ${error.message}</span>`;
                }
            }, 100);
        }
        
        function testLargeFile() {
            const result = document.getElementById('performance-result');
            result.innerHTML = '<span class="info">正在测试大文件处理...</span>';
            
            setTimeout(() => {
                try {
                    const editor = createMockEditor();
                    const code = editor.querySelector('code');
                    const lineNumbers = createMockLineNumbers();
                    
                    // 测试大文件（5000行）
                    const largeContent = Array.from({length: 5000}, (_, i) => `第${i + 1}行: 这是一个大文件的测试内容，包含更多的字符来模拟真实的代码文件`).join('\n');
                    
                    const startTime = performance.now();
                    code.textContent = largeContent;
                    
                    const lines = largeContent.split('\n');
                    const lineCount = lines.length;
                    const lineHeight = 21;
                    
                    // 使用文档片段优化性能
                    const fragment = document.createDocumentFragment();
                    for (let i = 1; i <= lineCount; i++) {
                        const lineDiv = document.createElement('div');
                        lineDiv.className = 'line-number';
                        lineDiv.textContent = i;
                        lineDiv.style.cssText = `
                            position: absolute;
                            top: ${(i - 1) * lineHeight + 10}px;
                            left: 0;
                            right: 0;
                            height: ${lineHeight}px;
                            line-height: ${lineHeight}px;
                            padding: 0 10px;
                            display: flex;
                            align-items: center;
                            justify-content: flex-end;
                            font-size: 14px;
                            color: #858585;
                            user-select: none;
                            pointer-events: none;
                            box-sizing: border-box;
                            font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Source Code Pro', 'Consolas', 'Monaco', 'Courier New', monospace;
                        `;
                        fragment.appendChild(lineDiv);
                    }
                    
                    lineNumbers.innerHTML = '';
                    lineNumbers.appendChild(fragment);
                    
                    const totalHeight = lineCount * lineHeight + 20;
                    lineNumbers.style.height = totalHeight + 'px';
                    
                    const endTime = performance.now();
                    const duration = endTime - startTime;
                    
                    result.innerHTML = `
<span class="success">大文件测试完成</span>

文件大小: ${lineCount} 行
处理时间: ${duration.toFixed(2)}ms
总高度: ${totalHeight}px
性能状态: ${duration < 1000 ? '✓ 优秀' : duration < 3000 ? '⚠ 良好' : '✗ 较慢'}

优化建议: 使用文档片段和虚拟滚动可以进一步提升大文件的性能
                    `;
                    
                } catch (error) {
                    result.innerHTML = `<span class="error">测试失败: ${error.message}</span>`;
                }
            }, 100);
        }
    </script>
</body>
</html> 